﻿#include "MiddleWidget.h"
#include "CustomWidget.h"
#include "AnimationStackedWidget.h"
#include "ConversationWidget.h"
#include "ContactsWidget.h"
#include "GroupWidget.h"
#include "ApplyWidget.h"
#include "ClientSocket.h"
#include "Msg.h"
#include "ChatWin.h"
#include "MyApp.h"
#include "global.h"
#include "DataBaseMagr.h"
#include "ClientFileSocket.h"
#include "CFileTask.h"

#include <QDateTime>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDebug>
#include <QLabel>
#include <QPainter>
#include <QPaintEvent>
#include <QJsonObject>
#include <QJsonArray>
#include <QScrollBar>
#include <QFont>

QColor MiddleWidget::color=QColor("#3bb1ea");
QColor MiddleWidget::bgcolor=QColor(250,250,250,100);

MiddleWidget::MiddleWidget(QWidget *parent)
    : BasedWidget(parent),
      m_pClientSocket(nullptr),
      m_pFileTask(nullptr),
      m_x(0),
      m_isDrawVerticalLine(false),
      m_isAnima(true),
      m_animation(this,"m_x")
{
    m_index=0;
    m_preindex=0;
    initUi();
    initConnect();
    initAnimation();
    initFileSocket();
}

MiddleWidget::~MiddleWidget()
{
    qDebug() << "MiddleWidget::~MiddleWidget()1";

    m_pClientFileSocket->StopSend();
    m_pClientFileSocket->StopRecv();
    m_pFileTask->Stop();
    //m_thread.terminate();           //强制结束
    m_thread.quit();
    m_pFileTask->wait();
    m_thread.wait();
    //清理窗口
    for(auto item : m_mapChatWin)
    {
        delete item;
    }
    qDebug() << "MiddleWidget::~MiddleWidget()2";
}

void MiddleWidget::setSocket(ClientSocket *pSocket)
{
    m_pClientSocket = pSocket;
    //connect(m_pClientSocket,&ClientSocket::sigFriendList,this,&MiddleWidget::SltGotFriendList);
    //connect(m_pClientSocket,&ClientSocket::sigUpdateUserStatus,this,&MiddleWidget::SltUpdateUserStatus);
    connect(this,&MiddleWidget::sigSend,m_pClientSocket,&ClientSocket::SltSend);
    connect(this,&MiddleWidget::sigSendToTargetid,m_pClientSocket,&ClientSocket::SltSendtoTargetid);
    //connect(m_pClientSocket,&ClientSocket::sigDelFriend,this,&MiddleWidget::SltDelFriendUpdateWidget);
    //connect(m_pClientSocket,&ClientSocket::sigChatMsg,this,&MiddleWidget::SltRecvChatMsg);
}

void MiddleWidget::addFriendToGroup(QQCellChild *child)
{
    m_pContactsWidget->addFriendToGroup(child);
}

void MiddleWidget::initUi()
{
    //设置背景色
    this->setAutoFillBackground(true); // 这句要加上, 否则可能显示不出背景图.
    QPalette palette = this->palette();
    palette.setColor(QPalette::Background,Qt::white);
    this->setPalette(palette);
    this->setMouseTracking(true);
    setMinimumSize(360,450);
    setMaximumSize(720,720);
    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    //按钮初始化
    m_pBtnStack[0]=new stackButton(":/Images/resource/images/conversation_normal.png",":/Images/resource/images/conversation_hover.png",":/Images/resource/images/conversation_select.png",this);
    m_pBtnStack[1]=new stackButton(":/Images/resource/images/contacts_normal.png",":/Images/resource/images/contacts_hover.png",":/Images/resource/images/contacts_select.png",this);
    m_pBtnStack[2]=new stackButton(":/Images/resource/images/group_normal.png",":/Images/resource/images/group_hover.png",":/Images/resource/images/group_select.png",this);
    m_pBtnStack[3]=new stackButton(":/Images/resource/images/applay_normal.png",":/Images/resource/images/applay_hover.png",":/Images/resource/images/applay_select.png",this);

    m_pBtnStack[0]->setFixedHeight(40);
    m_pBtnStack[1]->setFixedHeight(40);
    m_pBtnStack[2]->setFixedHeight(40);
    m_pBtnStack[3]->setFixedHeight(40);
    m_pBtnStack[0]->setselected(true);
    //按钮组
    m_pBtnGroup = new QButtonGroup(this);
    m_pBtnGroup->addButton(m_pBtnStack[0],0);
    m_pBtnGroup->addButton(m_pBtnStack[1],1);
    m_pBtnGroup->addButton(m_pBtnStack[2],2);
    m_pBtnGroup->addButton(m_pBtnStack[3],3);

    //按钮布局
    QHBoxLayout *hlyout=new QHBoxLayout;
    hlyout->addWidget(m_pBtnStack[0]);
    hlyout->addWidget(m_pBtnStack[1]);
    hlyout->addWidget(m_pBtnStack[2]);
    hlyout->addWidget(m_pBtnStack[3]);
    hlyout->setContentsMargins(0,0,0,0);
    hlyout->setSpacing(0);

    //栈窗口
    m_pStackWidget = new AnimationStackedWidget;
    //m_pStackWidget->setFrameShadow(QFrame::Raised);
    m_pConversationWidget = new ConversationWidget(this);
    m_pContactsWidget = new ContactsWidget(this);
    m_pGroupWidget = new GroupWidget(this);
    m_pApplyWidget = new ApplyWidget(this);

    m_pStackWidget->addWidget(m_pConversationWidget);
    m_pStackWidget->addWidget(m_pContactsWidget);
    m_pStackWidget->addWidget(m_pGroupWidget);
    m_pStackWidget->addWidget(m_pApplyWidget);
    //整体布局
    QVBoxLayout *vlayout = new QVBoxLayout;
    vlayout->addLayout(hlyout);
    vlayout->addWidget(m_pStackWidget);
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(0,0,0,0);
    //vlayout->addStretch(1);
    setLayout(vlayout);
}

void MiddleWidget::initConnect()
{
    connect(m_pBtnGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &MiddleWidget::SltStackPageChanged);
    connect(m_pContactsWidget,&ContactsWidget::sigDelFriend,this,&MiddleWidget::SltDelFriend);
    connect(m_pContactsWidget,&ContactsWidget::sigOpenChatWin,this,&MiddleWidget::SltOpenChatWin);
}

void MiddleWidget::initAnimation()
{
    m_pix=QPixmap(":/Images/resource/images/indicator.png");
    m_animation.setDuration(200);
    connect(&m_animation,SIGNAL(finished()),this,SLOT(Sltfinished()));
}

void MiddleWidget::initFileSocket()
{
    m_pClientFileSocket = new ClientFileSocket;
    m_pFileTask = new CFileTask(m_pClientFileSocket,this);
    m_pClientFileSocket->moveToThread(&m_thread);       //连同子类也移到到这个线程
    m_pFileTask->start();
    m_thread.start();
    connect(&m_thread,&QThread::finished,m_pClientFileSocket,&ClientSocket::deleteLater);
    connect(m_pFileTask,&QThread::finished,m_pFileTask,&QThread::deleteLater);
/*    connect(m_pClientSocket,&ClientSocket::signalStatus,this,&LoginAnimationWin::onTcpStatus);
    connect(this,&LoginAnimationWin::sigSend,m_pClientSocket,&ClientSocket::SltSend);
    connect(this,&LoginAnimationWin::sigConnectToHost,m_pClientSocket,&ClientSocket::ConnectToHost);
    Q_EMIT sigConnectToHost();
    */
}

/**
 * @brief MiddleWidget::paintEvent
 * _________________^_________________
 * |  first line   |  | second line  |
 */
void MiddleWidget::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    //p.setPen(Qt::transparent);
    //p.setBrush(bgcolor);//刷透明区域
    //p.drawRect(-1,-1,width(),height()+1);
    p.setPen(color);

   if(m_isAnima)
    {
       //这个注意一下有动画和没动画时line的计算方式，原因在于窗口缩放时不能用m_x计算，因为按钮长度都改变了
       if(m_isDrawVerticalLine)
       p.drawLine(width()-1,0,width()-1,height());//vertical line右边框线
        //first line
        p.drawLine(0,m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1,m_x+(m_pBtnStack[0]->width()-m_pix.width())/2-1,m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1);
        //second line
        p.drawLine(m_x+(m_pBtnStack[0]->width()-m_pix.width())/2+m_pix.width(),m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1,width(),m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1);
        p.drawPixmap(m_x+(m_pBtnStack[0]->width()-m_pix.width())/2,m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-m_pix.height()+1,m_pix);
    }
    else
    {
       if(m_isDrawVerticalLine)
       p.drawLine(width()-1,0,width()-1,height());

       p.drawLine(0,m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1,m_index*m_pBtnStack[0]->width()+(m_pBtnStack[0]->width()-m_pix.width())/2-1,m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1);
       p.drawLine(m_index*m_pBtnStack[0]->width()+(m_pBtnStack[0]->width()-m_pix.width())/2+m_pix.width(),m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1,width(),m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-1);
       p.drawPixmap(m_index*m_pBtnStack[0]->width()+(m_pBtnStack[0]->width()-m_pix.width())/2,m_pBtnStack[0]->y()+m_pBtnStack[0]->height()-m_pix.height()+1,m_pix);
    }
}

void MiddleWidget::resizeEvent(QResizeEvent *evt)
{
    Q_UNUSED(evt);
    //this->update();
    /*m_isAnima=true;
    m_animation.setStartValue(m_preindex*m_pBtnStack[0]->width());
    m_animation.setEndValue(m_index*m_pBtnStack[0]->width());
    m_animation.start();*/
}
/*
void MiddleWidget::mouseMoveEvent(QMouseEvent *evt)
{
    BasedWidget::mouseMoveEvent(evt);
    if(evt->pos().y() < m_pBtnStack[0]->height())
    {
        if(evt->pos().x() < (m_pBtnStack[0]->width() * 2) && evt->pos().x() > m_pBtnStack[0]->width())
        {
            m_pContactsWidget->verticalScrollBar()->setVisible(true);
        }else
        {
            m_pContactsWidget->verticalScrollBar()->setVisible(false);
        }
    }
}
*/
//切换不同栈页面，好友，群，会话，应用
void MiddleWidget::SltStackPageChanged(int index)
{
    m_preindex = m_index;
    m_index = index;

    if (m_preindex == m_index) return;
    m_pBtnStack[m_preindex]->setselected(false);

    m_isAnima=true;
    m_animation.setStartValue(m_preindex*m_pBtnStack[0]->width());
    m_animation.setEndValue(m_index*m_pBtnStack[0]->width());
    m_animation.start();

    m_pStackWidget->setLength(m_pStackWidget->width(),
                                   m_index > m_preindex
                                   ? AnimationStackedWidget::LeftToRight
                                   : AnimationStackedWidget::RightToLeft);

    m_pStackWidget->start(m_index);
}

//好友状态更新，对话框头像也需要更新
void MiddleWidget::updateUserStatus(int userid, const QString &groupName)
{
    m_pContactsWidget->updateUserStatus(userid,groupName);
    if(m_mapChatWin.find(userid) != m_mapChatWin.end())
    {
        ChatWin *chatwin = m_mapChatWin[userid];
        chatwin->UpdateWinInfo();
    }
}

//客户端弹出提示框：是否删除好友，避免误删
void MiddleWidget::SltDelFriend(int userid)
{
    bool ret = CMessageBox::Question(tr("Do you want to delete the friend?"),tr("Delete friend"));
    if(ret)
    {
        QJsonObject json;
        json.insert("userid",userid);
        json.insert("type",msg_type_delFriend);

        Q_EMIT  sigSend(msg_type_operatefriend,json);
    }
}

//删除好友，对应的需要删除的窗体：好友个人信息对话框、聊天对话框
void MiddleWidget::delFriendUpdateWidget(int userid)
{
    if(m_mapChatWin.find(userid) != m_mapChatWin.end())
    {
        ChatWin *chatwin = m_mapChatWin[userid];
        chatwin->SltClose();
    }
    m_pContactsWidget->DelFriendUpdateWidget(userid);
}

//打开好友聊天对话框
void MiddleWidget::SltOpenChatWin(QQCellChild *child)
{

    //ChatWin窗口关闭，发送信号通知这个map
    if(m_mapChatWin.find( child->m_id) == m_mapChatWin.end())
    {

        //该窗口关闭自动析构
        ChatWin *chatwin = new ChatWin;
        connect(chatwin,&ChatWin::sigCloseChatWin,this,&MiddleWidget::SltCloseChatWin);
        connect(chatwin,&ChatWin::sigSendMsg,this,&MiddleWidget::SltSendTextMsg);
        m_mapChatWin[child->m_id] = chatwin;
        chatwin->setQQCell(child);
        chatwin->setFileSocket(m_pClientFileSocket,m_pFileTask);
        //窗口打开等加载好了html以后，再打开，具体实现见Chatwin::SltLoadHistoryMsg

        //FIXME:不加processEvents,载入的历史消息打开窗口显示不出来，为什么？很迷惑
        //QCoreApplication::processEvents(QEventLoop::AllEvents);
        //child->m_UnReadMsg = 0;         //未读消息数清零
        //chatwin->activateWindow();
        //chatwin->showNormal();
        //myHelper::Sleep(1000);
        //chatwin->LoadHistoryMsg(HistoryMsg,child->m_UnReadMsg,10);
        //chatwin->LoadHistoryMsg(UnReadMsg,0,child->m_UnReadMsg);
    }
    else
    {
        ChatWin *chatwin = m_mapChatWin[child->m_id];
        chatwin->showNormal();
        chatwin->activateWindow();
    }
}

//关闭好友窗口的同时需要将其QQCellChild中的ChatWin置空
void MiddleWidget::SltCloseChatWin(int id)
{
    ChatWin* chatwin = m_mapChatWin[id];
    if(chatwin!=NULL)
    {
        QQCellChild * child = chatwin->getQQCell();
        child->m_pChatWin = NULL;
        m_mapChatWin.remove(id);
    }
}

//收到聊天消息
void MiddleWidget::recvChatMsg(const QJsonObject &json, int senderid,QQCellChild* child,const QString& groupName)
{
    QStringList fileInfo;
    //获取时间
    uint utcTime = json.value("time").toVariant().toUInt();

    //获取消息内容
    QJsonArray content = json.value("content").toArray();
    QString msgText;
    for(int i = 0;i<content.size();i++)
    {
        QString key = content[i].toObject().keys().at(0);
        if("faceID" == key)
        {
            int faceid = content[i].toObject().value("faceID").toInt();
            msgText += QString("<img src=qrc:/face/resource/Face/%1.gif>").arg(faceid);
        }else if("msgText" == key)
        {
            msgText += content[i].toObject().value("msgText").toString();
        }else if("shake" == key)
        {
            child->m_bShake = true;
            msgText = "☆对方给您发送了一个窗口抖动☆";
        }else if("file" == key)
        {
            //{"file":["日志系统的设计.zip","a9c16205582437436c740832da9ce2b9",324217,0]}
            QJsonArray jsonFileInfo = content[i].toObject().value("file").toArray();
            qDebug() << fileInfo;
            QString fileName = jsonFileInfo[0].toString();
            QString fileMd5 = jsonFileInfo[1].toString();
            int fileSize = jsonFileInfo[2].toInt();
            bool fileType = jsonFileInfo[3].toBool();
            qDebug() << " " << fileName << " " << fileMd5 << " " << fileSize << " " << fileType;
            msgText = QString("☆发送文件:%1☆").arg(fileName);
            child->m_bTransFlag = true;
            fileInfo << fileName << fileMd5 << QString("%1").arg(fileSize) << QString("%1").arg(fileType);
            //文件信息放入接收队列
            (child->m_listFileInfo) << fileInfo;
        }
    }
    qDebug() << msgText;
    //获取字体
    QFont font;
    QString fontToDatabase;

    if(json.value("font").isUndefined())
    {
        //有些消息没有发送字体信息，比如窗口抖动，离线文件传输，那么使用默认字体
        QString&& family = "黑体";
        int pointSize = 16;
        bool bold = false;
        bool italic = false;
        bool underline = false;
        font = QFont(family,pointSize,QFont::Normal,italic);
        font.setUnderline(underline);
        fontToDatabase = QString("%1,%2,%3,%4,%5,%6")
              .arg(family).arg(pointSize).arg(bold).arg(italic).arg(underline).arg(0);

    }else
    {
        QJsonArray jsonFont = json.value("font").toArray();
        QString&& family = jsonFont[0].toString();
        int pointSize = jsonFont[1].toInt();
        bool bold = jsonFont[3].toInt();
        QFont::Weight w = bold ? QFont::Bold : QFont::Normal;
        bool italic = jsonFont[4].toInt();
        bool underline = jsonFont[5].toInt();
        font = QFont(family,pointSize,w,italic);
        font.setUnderline(underline);
        fontToDatabase = QString("%1,%2,%3,%4,%5,%6")
                .arg(family).arg(pointSize).arg(bold).arg(italic).arg(underline).arg(0);
    }

    //消息插入数据库
    DataBaseMagr::Instance()->AddHistoryMsg(senderid,1,utcTime,fontToDatabase,msgText);


    if(m_mapChatWin.find(senderid) != m_mapChatWin.end())
    {
        //如果打开聊天窗口直接插入消息就行
        ChatWin *chatwin = m_mapChatWin[senderid];
        chatwin->activateWindow();
        chatwin->show();
        QApplication::alert(chatwin);
        chatwin->InsertChatMsg(utcTime,font,msgText);
        //窗口抖动
        if(child->m_bShake)
        {
            chatwin->ShakeWin("☆对方给您发送了一个窗口抖动☆");
            child->m_bShake = false;        //清除抖动标记
        }
        //接收文件
        if(child->m_bTransFlag)
        {
            chatwin->RecvFile((child->m_listFileInfo).takeFirst());
            child->m_bTransFlag = false;    //清除文件接收标记
        }
    }else
    {
        //没有打开聊天窗口,通知好友界面消息到来，头像闪烁
        //child->m_UnReadMsg++;
        child->SetUnReadMsg();
    }

}

void MiddleWidget::SltSendTextMsg(const QJsonObject &json, int targetid)
{
    Q_EMIT sigSendToTargetid(msg_type_chat,json,targetid);
}
